﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using System.Collections.Specialized;

namespace NETXPF.Library
{
    /// <summary>
    /// Utility methods for the web.
    /// </summary>
    public static class WebUtils
    {
        /// <summary>
        /// Compresses output from this point forward using either GZip or Deflate, depending on client-accepted encoding.
        /// </summary>
        /// <param name="context">Current context</param>
        public static void CompressOutput(System.Web.HttpContext context)
        {
            IOUtils.GZipEncodePage(context);
        }
        /// <summary>
        /// Another "fix" to .NET's ugly HTTP API
        /// This one allows you to create a web request without casting
        /// </summary>
        /// <param name="uri"></param>
        /// <returns></returns>
        public static HttpWebRequest Request(Uri uri)
        {
            return (HttpWebRequest)HttpWebRequest.Create(uri);
        }
        /// <summary>
        /// Doing a POST request is cumbersome in C#:
        /// http://www.terminally-incoherent.com/blog/2008/05/05/send-a-https-post-request-with-c/
        /// 
        /// This method aims to simplify it a bit.
        /// </summary>
        /// <param name="wr"></param>
        /// <param name="postData"></param>
        /// <returns></returns>
        public static HttpWebResponse Post(HttpWebRequest wr, NameValueCollection postData)
        {
            wr.Method = "POST";

            // turn our request string into a byte stream
            byte[] postBytes = Encoding.ASCII.GetBytes(ConvertEx.URLEncodeNVPs(postData));

            // this is important - make sure you specify type this way
            wr.ContentType = "application/x-www-form-urlencoded";
            wr.ContentLength = postBytes.Length;
            Stream requestStream = wr.GetRequestStream();

            // now send it
            requestStream.Write(postBytes, 0, postBytes.Length);
            requestStream.Close();

            // grab the response
            HttpWebResponse response = (HttpWebResponse)wr.GetResponse();
            return response;
        }
        /// <summary>
        /// Calls a web service that was implemented with NETXPF.Web.ProcessServiceRequest.
        /// </summary>
        /// <typeparam name="T">Return type for this operation</typeparam>
        /// <param name="cookies">If service uses cookies, supply a cookie container here</param>
        /// <param name="serviceUri">URI of operation to execute</param>
        /// <param name="input">Input data passed along to service</param>
        /// <returns>Object returned by service</returns>
        public static T CallService<T>(CookieContainer cookies, Uri serviceUri, T input)
        {
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(serviceUri);
            req.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
            if (cookies != null)
            {
                req.CookieContainer = cookies;
            }
            req.Method = "POST";
            using (Stream s = req.GetRequestStream())
            {
                NETXPF.Library.Persist.ToXML(s, input);
            }
            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
            if (resp.StatusCode != HttpStatusCode.OK)
            {
                throw new Exception("Request failed, error: " + resp.StatusCode.ToString());
            }
            using (Stream s = resp.GetResponseStream())
            {
                return NETXPF.Library.Persist.FromXML<T>(s);
            }
        }
    }
}
